package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.DynamicDao;
import com.xbongbong.saas.domain.entity.DynamicEntity;
import com.xbongbong.saas.domain.entity.SmsStatusEntity;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.SmsStatusEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.DynamicModel;
import com.xbongbong.saas.model.IndexTypeModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


@Service("dynamicModel")
public class DynamicModelImpl implements DynamicModel {

    private final Logger LOG = LoggerFactory.getLogger(DynamicModelImpl.class);

    @Resource
    private DynamicDao dynamicDao;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    private static final String DYNAMIC_USER_SEND_SMS = "constant.logMemo.crm_dynamic_user_send_sms";

    @Override
    public Integer insert(DynamicEntity dynamicEntityExt) {
        boolean canInsert = checkAndParseDynamic(dynamicEntityExt);
        if (canInsert) {
            return dynamicDao.insert(dynamicEntityExt);
        } else {
            return 0;
        }
    }

    @Override
    public void insertBatch(List<DynamicEntity> dynamicEntities) {
        if (CollectionUtils.isNotEmpty(dynamicEntities)) {
            dynamicEntities = dynamicEntities.stream().filter(temp -> checkAndParseDynamic(temp)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(dynamicEntities)) {
                return;
            }
            dynamicDao.insertList(dynamicEntities);
        }
    }

    /**
     * 检查动态是否符合插入要求和解析处理部分参数值
     * @param dynamicEntity
     * @return
     */
    private boolean checkAndParseDynamic(DynamicEntity dynamicEntity) {
        if (Objects.isNull(dynamicEntity)) {
            return false;
        }
        long zero = 0L;
        // 此处主业务id的判断是为了兼容paas动态出现的问题（即使id为0也会往表中添加数据）
        boolean hasCustomerId = Objects.nonNull(dynamicEntity.getCustomerId()) && !Objects.equals(dynamicEntity.getCustomerId(), zero);
        boolean hasContactId = Objects.nonNull(dynamicEntity.getContactId()) && !Objects.equals(dynamicEntity.getContactId(), zero);
        boolean hasContractId = Objects.nonNull(dynamicEntity.getContractId()) && !Objects.equals(dynamicEntity.getContractId(), zero);
        boolean hasOpportunityId = Objects.nonNull(dynamicEntity.getOpportunityId()) && !Objects.equals(dynamicEntity.getOpportunityId(), zero);
        boolean canInsert =  hasCustomerId || hasContactId || hasContractId || hasOpportunityId;
        if (canInsert) {
            Long addTime = dynamicEntity.getAddTime();
            Long updateTime = dynamicEntity.getUpdateTime();
            long now = DateUtil.getInt();
            if (Objects.isNull(addTime)) {
                dynamicEntity.setAddTime(now);
            }
            if (Objects.isNull(updateTime)) {
                dynamicEntity.setUpdateTime(now);
            }
            if (Objects.isNull(dynamicEntity.getDel())) {
                dynamicEntity.setDel(0);
            }
            // 限制memo的长度
            String memo = dynamicEntity.getMemo();
            if (StringUtil.isNotEmpty(memo)) {
                memo = memo.length() <= 255 ? memo : memo.substring(0, 252) + "...";
                dynamicEntity.setMemo(memo);
            }
            // 限制ref_name的长度
            String refName = dynamicEntity.getRefName();
            if (StringUtil.isNotEmpty(refName)) {
                refName = refName.length() <= 100 ? refName : refName.substring(0, 97) + "...";
                dynamicEntity.setRefName(refName);
            }
        }
        return canInsert;
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return dynamicDao.getEntitysCount(param);
    }

    @Override
    public Integer update(DynamicEntity entity) throws XbbException {
        if(Objects.nonNull(entity)){
            return dynamicDao.update(entity);
        }
        return null;
    }

    @Override
    public List<DynamicEntity> findEntitys(Map<String, Object> param) {
        return dynamicDao.findEntities(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public void updateData(Map<String, Object> params) {
        if (Objects.nonNull(params) && params.size() > 0) {
            dynamicDao.updateData(params);
        }
    }

    @Override
    public void insertSmsSendDynamic(SmsStatusEntity smsStatusEntity) {
        try {
            if (Objects.nonNull(smsStatusEntity) && Objects.equals(SmsStatusEnum.SEND_ING.getCode(), smsStatusEntity.getStatus())) {
                String corpid = smsStatusEntity.getCorpid();
                Set<String> mobiles = new HashSet<>();
                if (smsStatusEntity.getMobile().contains(StringConstant.COMMA)) {
                    String[] ms = smsStatusEntity.getMobile().split(StringConstant.COMMA);
                    mobiles.addAll(Arrays.asList(ms));
                } else {
                    mobiles.add(smsStatusEntity.getMobile());
                }
                List<DynamicEntity> dynamicEntities = new ArrayList<>();
                Map<String, PaasFormDataEntityExt> customerMobileToCustomerInfoMap = getCustomerMobileToCustomerInfoMap(corpid, mobiles);
                fillSendSmsDynamicEntity(dynamicEntities, smsStatusEntity, customerMobileToCustomerInfoMap, mobiles, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                Map<String, PaasFormDataEntityExt> contactMobileToContactInfoMap = getContactMobileToContactInfoMap(corpid, mobiles);
                fillSendSmsDynamicEntity(dynamicEntities, smsStatusEntity, contactMobileToContactInfoMap, mobiles, XbbRefTypeEnum.CONTACT.getCode());
                insertBatch(dynamicEntities);
            }
        } catch (Exception e) {
            LOG.error("com.xbongbong.saas.model.impl.DynamicModelImpl.insertSmsSendDynamic", e);
        }
    }

    private Map<String, PaasFormDataEntityExt> getContactMobileToContactInfoMap(String corpid, Set<String> mobiles) throws XbbException {
        return getMobileToPaasFormDataMap(corpid, mobiles, XbbRefTypeEnum.CONTACT.getCode(), ContactEnum.PHONE.getAttr());
    }

    private Map<String, PaasFormDataEntityExt> getCustomerMobileToCustomerInfoMap(String corpid, Set<String> mobiles) throws XbbException {
        return getMobileToPaasFormDataMap(corpid, mobiles, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), CustomerManagementEnum.PHONE.getAttr());
    }

    private Map<String, PaasFormDataEntityExt> getMobileToPaasFormDataMap(String corpid, Set<String> mobiles, Integer businessType, String phoneAttr) throws XbbException {
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(StringConstant.CORPID, corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Map<String, List> mobileMap = new HashMap<>();
        mobileMap.put("data." + phoneAttr + ".text_2.keyword", new ArrayList(mobiles));
        params.put("should", mobileMap);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormData = paasEsModel.selectByCondition(businessType, null, params,indexTypeEnum);
        // Set<Long> formIds = paasFormData.stream().map(PaasFormDataEntityExt::getFormId).collect(Collectors.toSet());
        // Map<Long, PaasFormEntity> formIdToPaasFormMap = proFormHelp.getPaasFormList(corpid, businessType, formIds).stream().collect(Collectors.toMap(PaasFormEntity::getId, item -> item));
        Map<String, PaasFormDataEntityExt> mobileToPassFormDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormData) {
            JSONObject data = paasFormDataEntityExt.getData();
            JSONArray phone = data.getJSONArray(phoneAttr);
            for (JSONObject mobile : phone.toJavaList(JSONObject.class)) {
                mobileToPassFormDataMap.put(mobile.getString("text_2"), paasFormDataEntityExt);
            }
            // PaasFormEntity paasFormEntity = formIdToPaasFormMap.get(paasFormDataEntityExt.getFormId());
            // if (Objects.nonNull(paasFormEntity)) {
            //     paasFormDataEntityExt.setBusinessType(paasFormEntity.getBusinessType());
            // }
        }
        return mobileToPassFormDataMap;
    }

    private void fillSendSmsDynamicEntity(List<DynamicEntity> dynamicEntities, SmsStatusEntity smsStatusEntity, Map<String, PaasFormDataEntityExt> mobileToPaasFormDataMap, Set<String> mobiles, Integer businessType) {
        if (!mobileToPaasFormDataMap.isEmpty()) {
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            for (String mobile : mobiles) {
                DynamicEntity dynamicEntity = new DynamicEntity();
                dynamicEntity.setCorpid(smsStatusEntity.getCorpid());
                PaasFormDataEntityExt paasFormData = mobileToPaasFormDataMap.get(mobile);
                if (Objects.isNull(paasFormData)) {
                    continue;
                }
                JSONObject data = paasFormData.getData();
                String receiverName = null;
                switch (xbbRefTypeEnum) {
                    case CUSTOMER_MANAGEMENT:
                        dynamicEntity.setCustomerId(paasFormData.getId());
                        receiverName = data.getString(CustomerManagementEnum.NAME.getAttr());
                        receiverName = Objects.nonNull(receiverName) ? receiverName : "";
                        dynamicEntity.setLogType(ProjectLogEnum.CUSTOMER_SMS.getSubType());
                        break;
                    case CONTACT:
                        dynamicEntity.setContactId(paasFormData.getId());
                        receiverName = data.getString(ContactEnum.NAME.getAttr());
                        receiverName = Objects.nonNull(receiverName) ? receiverName : "";
                        dynamicEntity.setLogType(ProjectLogEnum.CONTACT_SMS.getSubType());
                        break;
                    default:
                        break;
                }
                if (Objects.nonNull(receiverName)) {
                    dynamicEntity.setCreatorId(smsStatusEntity.getUserId());
                    String memo = String.format(I18nMessageUtil.getMessage(DYNAMIC_USER_SEND_SMS), smsStatusEntity.getSender(), receiverName + ":" + mobile, smsStatusEntity.getContent());
                    dynamicEntity.setMemo(memo);
                    dynamicEntity.setAddTime(smsStatusEntity.getSendTime());
                    dynamicEntity.setUpdateTime(smsStatusEntity.getSendTime());
                    dynamicEntity.setDel(DelEnum.NORMAL.getDel());
                    dynamicEntities.add(dynamicEntity);
                }
            }
        }
    }
}
